home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 140 / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin / tools / dshell / dsh333bs.lzh / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-05  |  2.4 KB  |  164 lines

  1. /*
  2.     dshell    v3
  3.  
  4.     文字列式評価
  5. */
  6.  
  7. #include    "dsh.h"
  8. #include    <setjmp.h>
  9.  
  10. static jmp_buf toAbort;
  11. static uchar *pp;
  12.  
  13. #define    skipBlank(x) ({ \
  14.     uchar *_p = (x), _c; \
  15.     while ((_c = *_p++) == '\x20' || _c == '\t') \
  16.         ; \
  17.     _p - 1; \
  18. }) \
  19.  
  20.  
  21. static volatile void evalError(void)
  22. {
  23.     longjmp(toAbort, -1);
  24. }
  25.  
  26. static int evalOR(void);
  27. static int evalCMP(void)
  28. {
  29.     int val;
  30.     uchar c1, c2, *s1, *s2, *e1, *e2, *p;
  31.     uchar cond;
  32.     enum {
  33.         condLT, condLE, condEQ, condNE, condGE, condGT,
  34.     };
  35.  
  36.     p = skipBlank(pp);
  37.     c1 = *p++;
  38.     if (c1 == '\0' || iskanji1(c1))
  39.         evalError();
  40.     if (c1 == '(') {
  41.         pp = p;
  42.         val = evalOR();
  43.         p = skipBlank(pp);
  44.         if (*p++ != ')')
  45.             evalError();
  46.         pp = p;
  47.         return val;
  48.     }
  49.     if (c1 == '.' && strnEqu(p + 1, "not.", 4)) {
  50.         pp = p + 5;
  51.         return !evalOR();
  52.     }
  53.     s1 = p;
  54.     p += dinstrchr(p, c1);
  55.     if (p == s1)
  56.         evalError();
  57.     e1 = p;
  58.     p = skipBlank(p);
  59.  
  60.     if (*p++ != '.')
  61.         evalError();
  62.     if (strnEqu(p, "lt.", 3))
  63.         cond = condLT;
  64.     else if (strnEqu(p, "le.", 3))
  65.         cond = condLE;
  66.     else if (strnEqu(p, "eq.", 3))
  67.         cond = condEQ;
  68.     else if (strnEqu(p, "ne.", 3))
  69.         cond = condNE;
  70.     else if (strnEqu(p, "ge.", 3))
  71.         cond = condGE;
  72.     else if (strnEqu(p, "gt.", 3))
  73.         cond = condGT;
  74.     else
  75.         evalError();
  76.     p = skipBlank(p + 3);
  77.  
  78.     c2 = *p++;
  79.     if (c2 == '\0' || iskanji1(c2))
  80.         evalError();
  81.     s2 = p;
  82.     p += dinstrchr(p, c2);
  83.     if (p == s2)
  84.         evalError();
  85.     e2 = p;
  86.     pp = p;
  87.     *--e1 = '\0';
  88.     *--e2 = '\0';
  89.     val = strcmp(s1, s2);
  90.     *e1 = c1;
  91.     *e2 = c2;
  92.  
  93.     switch (cond) {
  94.     case condLT:
  95.         val = (val < 0);
  96.         break;
  97.     case condLE:
  98.         val = (val <= 0);
  99.         break;
  100.     case condEQ:
  101.         val = (val == 0);
  102.         break;
  103.     case condNE:
  104.         val = (val != 0);
  105.         break;
  106.     case condGE:
  107.         val = (val >= 0);
  108.         break;
  109.     case condGT:
  110.         val = (val > 0);
  111.         break;
  112.     }
  113.     return val;
  114. }
  115.  
  116.  
  117. static int evalAND(void)
  118. {
  119.     uchar *p;
  120.     int val;
  121.  
  122.     val = evalCMP();
  123.     p = pp;
  124.     for (;;) {
  125.         p = skipBlank(p);
  126.         if (*p == '.' && strnEqu(p + 1, "and.", 4)) {
  127.             pp = p + 5;
  128.             val &= evalCMP();
  129.             p = pp;
  130.         } else
  131.             break;
  132.     }
  133.     return val;
  134. }
  135.  
  136.  
  137. static int evalOR(void)
  138. {
  139.     uchar *p;
  140.     int val;
  141.  
  142.     val = evalAND();
  143.     p = pp;
  144.     for (;;) {
  145.         p = skipBlank(p);
  146.         if (*p == '.' && strnEqu(p + 1, "or.", 3)) {
  147.             pp = p + 4;
  148.             val |= evalAND();
  149.             p = pp;
  150.         } else
  151.             break;
  152.     }
  153.     return val;
  154. }
  155.  
  156.  
  157. int evalCond(uchar *p)
  158. {
  159.     if (setjmp(toAbort) != 0)
  160.         return -1;
  161.     pp = p;
  162.     return evalOR();
  163. }
  164.